package com.JingYan.Thread;

import com.sun.org.apache.bcel.internal.generic.NEW;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 线程等待和唤醒
 *
 * @author Dong_Jia_Qi on 2022/6/4
 */
public class TaskQueue {
    Queue<String> queue = new LinkedList<>();
    private final Lock lock  = new ReentrantLock();
    private final Condition condition = lock.newCondition();

    /**
     * 往队列里增加数据
     * @param s 数据
     */
    public synchronized  void  addTask(String s){
        this.queue.add(s);
        //唤醒 this 锁 锁住的等待状态的线程
        this.notifyAll();
    }

    /**
     * 获得线程第一个数据
     * @return
     * @throws InterruptedException
     */
    public synchronized String getTask() throws InterruptedException {
        while (queue.isEmpty()){
            //进入等待状态
            this.wait();
        }
        Thread.sleep(100);
        //弹栈
        return queue.remove();
    }

    /**
     * 可重入锁添加数据
     * @param s
     */
    public void reenAddTask(String s){
        lock.lock();
        try {
            queue.add(s);
            //唤醒
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 可重入锁获取
     * `tryLock()`类似，`await()`可以在等待指定时间后，如果还没有被其他线程通过`signal()`或`signalAll()`唤醒，可以自己醒来
     * @return
     */
    public String reenGetTask() {
        lock.lock();
        try {
            while (queue.isEmpty()) {
                condition.await();
            }
            return queue.remove();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return "";
    }


}
